﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WarOfDev.EF;
using WarOfDev.Core.Common;
using WarOfDev.Core;
using WarOfDev.Core.Configuration;
using System.IO;
using System.Drawing;

namespace WarOfDev.Web.Controllers
{
    public class CateController : BaseController
    {
        private WarDevEntities db = new WarDevEntities();

        //
        // GET: /Cate/

        public ActionResult Index()
        {
            ViewBag.currentDeveloperId = this.CurrentUser.Id;
            return View(db.Posts.Where(p=>p.PostType==(int)EnumPostType.Cate).ToList());
        }

        //
        // GET: /Cate/Details/5

        public ActionResult Details(string id = null)
        {
            Post post = db.Posts.Single(p => p.Id == id);
            ViewBag.currentDeveloperId = this.CurrentUser.Id;

            if (post == null)
            {
                return HttpNotFound();
            }
            return View(post);
        }

        //
        // GET: /Cate/Create

        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Cate/Create

        [HttpPost]
        public ActionResult Create(Post post)
        {
            if (ModelState.IsValid)
            {
                post.Id = Guid.NewGuid().ToString();

                post.CreatedOn = post.ModifiedOn = DateTime.Now;
                post.CreatedBy = post.ModifiedBy = this.CurrentUser.Id;
                post.PostType = (int)EnumPostType.Cate;


                var tags = post.Tags.Split(',');
                
                var oldTags = from tag in db.Tags
                              where tags.Contains(tag.TagName)
                              select tag.TagName;

                var newTags = tags.Except(oldTags);
                newTags.ToList().ForEach(t =>
                    db.Tags.AddObject(new Tag()
                    {
                        TagName = t,
                        CreateOn = DateTime.Now,
                        CreateBy = this.CurrentUser.Id
                    })
                );

                var tagClouds = new List<TagCloud>();
                foreach (string tag in tags)
                {
                    tagClouds.Add(new TagCloud { 
                        Id=Guid.NewGuid().ToString(),
                        PostId=post.Id,
                        CreatedBy=this.CurrentUser.Id,
                        CreatedOn=DateTime.Now,
                        TagName=tag
                    });
                }

                var onwer = db.Developers.Single(d => d.Id == this.CurrentUser.Id);
                onwer.ExperienceValue += DefaultExperienceValueSetting.AddCate;
                onwer.GameLevel = ExperienceValueSetting.GetLevelByExperienceValue(onwer);
                

                onwer.ModifiedOn = DateTime.Now;
                onwer.ModifiedBy = onwer.Id;
                db.ObjectStateManager.ChangeObjectState(onwer, EntityState.Modified);


                var link = new MessageLink
                {
                    Id = Guid.NewGuid().ToString(),
                    LinkText = post.Title,
                    LinkHref = Url.Action("Details", "Cate", new { id = post.Id }),
                    CreatedBy = this.CurrentUser.Id,
                    CreatedOn = DateTime.Now
                };

                var message = new Message
                {
                    Id = Guid.NewGuid().ToString(),
                    CreatedBy = this.CurrentUser.Id,
                    CreatedOn = DateTime.Now,
                    MessageContent = string.Format("{0} gave us a cate, have a look at it : ",
                           this.CurrentUser.NickName)
                };

                message.Links.Add(link);

                // add experience value history
                ExperienceValueHistory history = new ExperienceValueHistory
                {
                    CreatedBy = this.CurrentUser.Id,
                    CreatedOn = DateTime.Now,
                    DeveloperId = this.CurrentUser.Id,
                    Id = Guid.NewGuid().ToString(),
                    FromAction = (int)EnumChangeExperienceValueAction.PostCate,
                    ChangedExperienceValue = DefaultExperienceValueSetting.AddCate
                };
                db.ExperienceValueHistorys.AddObject(history);

                tagClouds.ForEach(t=>db.TagClouds.AddObject(t));
                
                db.Messages.AddObject(message);
                db.Posts.AddObject(post);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(post);
        }

        
        [HttpPost]
        public ActionResult Comment(string cateId,string anwser,string startRating)
        {
            if (ModelState.IsValid)
            {
                Comment comment = new Comment
                {
                    Id = Guid.NewGuid().ToString(),
                    PostId = cateId,
                    CommendType = (int)EnumPostType.Cate,
                    CreateOn = DateTime.Now,
                    ModifiedOn = DateTime.Now,
                    CreateBy = this.CurrentUser.Id,
                    ModifiedBy = this.CurrentUser.Id,
                    Commend = anwser,
                };

                var startRatingItem=DefaultExperienceValueSetting.StartRatingList.SingleOrDefault(i => i.Value == startRating);

                int addedStartRating = 0;
                int.TryParse(startRating, out addedStartRating);

                comment.ExperienceValue = addedStartRating;

                db.Comments.AddObject(comment);

                // update experience value of post's author
                var onwers = from post in db.Posts
                            where post.Id == cateId
                            join develop in db.Developers on post.CreatedBy equals develop.Id
                            select develop;


                var onwer = onwers.ToList()[0];
                db.Developers.Attach(onwer);
                onwer.ExperienceValue += addedStartRating;

                // add experience value history
                ExperienceValueHistory history = new ExperienceValueHistory
                {
                    CreatedBy = this.CurrentUser.Id,
                    CreatedOn = DateTime.Now,
                    DeveloperId = onwer.Id,
                    Id = Guid.NewGuid().ToString(),
                    FromAction = (int)EnumChangeExperienceValueAction.BeCommentedByCate,
                    ChangedExperienceValue = addedStartRating
                };
                db.ExperienceValueHistorys.AddObject(history);

                db.SaveChanges();
                return RedirectToAction("Details", new { id = cateId });
            }

            return View("Details");
        }

        //
        // GET: /Cate/Edit/5

        public ActionResult Edit(string id = null)
        {
            Post post = db.Posts.Single(p => p.Id == id);
            if (post == null)
            {
                return HttpNotFound();
            }
            return View(post);
        }


        public ActionResult Tags(EnumPostType postType)
        {
            var tags = from tagCloud in db.TagClouds
                       join p in db.Posts on tagCloud.PostId equals p.Id
                       where p.PostType == (int)postType
                       group tagCloud by tagCloud.TagName into tag
                       select new 
                       {
                          tagName= tag.Key,
                          count=tag.Count()
                       };

            var maxCount= tags.Max(t => t.count);

            var result = new List<Models.TagModel>();
            var maxWeight=15;

            tags.ToList().ForEach(t =>
            {
                var model = new Models.TagModel
                {
                    text = t.tagName,
                    link=Url.Action("Tag",new{ tag= t.tagName })
                };

                if (t.count == maxCount && t.count > 1)
                {
                    model.weight = maxWeight;
                }
                else if (t.count == 1)
                {
                    model.weight = 1;
                }
                else
                {
                    model.weight = t.count / maxCount / maxWeight;
                }

                result.Add(model);
            });

                      


            return new JsonResult
            {
                Data = result
            };
        }

        //
        // POST: /Cate/Edit/5

        [HttpPost]
        public ActionResult Edit(Post post)
        {
            if (ModelState.IsValid)
            {
                db.Posts.Attach(post);
                db.ObjectStateManager.ChangeObjectState(post, EntityState.Modified);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(post);
        }

        //
        // GET: /Cate/Delete/5

        public ActionResult Delete(string id = null)
        {
            Post post = db.Posts.Single(p => p.Id == id);
            if (post == null)
            {
                return HttpNotFound();
            }
            return View(post);
        }

        //
        // POST: /Cate/Delete/5

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(string id)
        {
            Post post = db.Posts.Single(p => p.Id == id);
            db.Posts.DeleteObject(post);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}